package com.sbdev.plugin;


import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.Properties;
/**
 * 消费时间插件，用于拦截MyBatis的Executor执行查询操作，计算查询操作的消耗时间。
 * 该插件通过实现Interceptor接口，利用MyBatis的插件机制，在查询执行前后插入计时逻辑。
 */
@Intercepts(
        @Signature(
                type = Executor.class,
                method = "query",
                args = {
                        MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class
                }))
public class ConsumptionTimePlugin implements Interceptor {

    /**
     * 对Executor的query方法进行拦截。
     * 在执行查询操作前后记录时间，以计算查询操作的耗时，并输出到控制台。
     *
     * @param invocation 查询操作的调用信息，包含执行查询所需的所有参数。
     * @return 查询操作的结果对象。
     * @throws Throwable 查询操作中可能抛出的任何异常。
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 记录查询开始时间
        long start = System.currentTimeMillis();
        // 执行查询操作
        Object returnObj = invocation.proceed();
        // 记录查询结束时间
        long end = System.currentTimeMillis();
        // 计算并输出查询耗时
        System.out.println("耗时【" + (end - start)+"】毫秒");
        return returnObj;
    }

    /**
     * 为指定的目标对象创建一个插件代理。
     * 该方法用于实现插件的包装逻辑，将当前插件应用于目标对象，以拦截目标对象的方法调用。
     *
     * @param target 被插件化的对象，即MyBatis的Executor实例。
     * @return 包装了当前插件的目标对象的代理实例。
     */
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    /**
     * 设置插件的属性。
     * 该方法用于接收从配置文件中读取的插件属性，当前插件未使用任何属性，因此该方法为空实现。
     *
     * @param properties 插件的属性配置。
     */
    @Override
    public void setProperties(Properties properties) {
        // 该插件不使用任何属性，因此该方法为空实现
    }
}
